{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# भाग 4: मॉडल एवरेजिंग के साथ फेडरेटेड लर्निंग\n",
    "\n",
    "**रिकैप:** इस ट्यूटोरियल के भाग 2 में, हमने फेडरेटेड लर्निंग के एक बहुत ही सरल संस्करण का उपयोग करके एक मॉडल को प्रशिक्षित किया। इसके लिए प्रत्येक डेटा अधिकारी को अपने ग्रेडिएंट को देखने में सक्षम होने के लिए मॉडल अधिकारी पर भरोसा करना आवश्यक था।\n",
    "\n",
    "**विवरण:** इस ट्यूटोरियल में, हम दिखाएंगे कि अंतिम परिणामी मॉडल, मॉडल के अधिकारी को (हमें), वापस भेजे जाने से पहले एक विश्वसनीय \"सुरक्षित कर्मचारी\" द्वारा भार को अनुमति देने के लिए भाग 3 से उन्नत एकत्रीकरण उपकरण का उपयोग कैसे करें।\n",
    "\n",
    "इस तरह, केवल सुरक्षित कर्मचारी ही देख सकते हैं कि किसका वजन किसके पास से आया है। हम यह बताने में सक्षम हो सकते हैं कि मॉडल के कौन से हिस्से बदले गए, लेकिन हम यह नहीं जानते कि कौन सा कार्यकर्ता (बॉब या ऐलिस) कौन सा परिवर्तन करता है, जो गोपनीयता की एक परत बनाता है।\n",
    "\n",
    "लेखक:\n",
    " - Andrew Trask - Twitter: [@iamtrask](https://twitter.com/iamtrask)\n",
    " - Jason Mancuso - Twitter: [@jvmancuso](https://twitter.com/jvmancuso)\n",
    " \n",
    " nbTranslate का उपयोग करके अनुवादित\n",
    "\n",
    "संपादक:\n",
    "\n",
    " - Urvashi Raheja - Github: [@raheja](https://github.com/raheja)\n",
    " \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import syft as sy\n",
    "import copy\n",
    "hook = sy.TorchHook(torch)\n",
    "from torch import nn, optim"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 1: डेटा अधिकारी बनाएँ\n",
    "\n",
    "सबसे पहले, हम दो डेटा अधिकारी (बॉब और ऐलिस) बनाने जा रहे हैं, जिनमें से प्रत्येक के पास कम डेटा है। हम \"secure_worker\" नामक एक सुरक्षित मशीन को इनिशियलाइज़ करने जा रहे हैं। व्यवहार में यह सुरक्षित हार्डवेयर हो सकता है (जैसे इंटेल का SGX) या केवल एक विश्वसनीय मध्यस्थ।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a couple workers\n",
    "\n",
    "bob = sy.VirtualWorker(hook, id=\"bob\")\n",
    "alice = sy.VirtualWorker(hook, id=\"alice\")\n",
    "secure_worker = sy.VirtualWorker(hook, id=\"secure_worker\")\n",
    "\n",
    "\n",
    "# A Toy Dataset\n",
    "data = torch.tensor([[0,0],[0,1],[1,0],[1,1.]], requires_grad=True)\n",
    "target = torch.tensor([[0],[0],[1],[1.]], requires_grad=True)\n",
    "\n",
    "# get pointers to training data on each worker by\n",
    "# sending some training data to bob and alice\n",
    "bobs_data = data[0:2].send(bob)\n",
    "bobs_target = target[0:2].send(bob)\n",
    "\n",
    "alices_data = data[2:].send(alice)\n",
    "alices_target = target[2:].send(alice)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 2: हमारा मॉडल बनाएं\n",
    "\n",
    "इस उदाहरण के लिए, हम एक सरल रैखिक (Linear) मॉडल के साथ प्रशिक्षित करने जा रहे हैं। हम इसे प्रारंभिक रूप से PyTorch के nn.Linear कंस्ट्रक्टर का उपयोग करके शुरू कर सकते हैं।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Iniitalize A Toy Model\n",
    "model = nn.Linear(2,1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 3: ऐलिस और बॉब को मॉडल की एक प्रति भेजें\n",
    "\n",
    "अगला, हमें एलिस और बॉब को वर्तमान मॉडल की एक प्रति भेजने की आवश्यकता है ताकि वे अपने स्वयं के डेटासेट पर सीखने के चरणों का प्रदर्शन कर सकें।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bobs_model = model.copy().send(bob)\n",
    "alices_model = model.copy().send(alice)\n",
    "\n",
    "bobs_opt = optim.SGD(params=bobs_model.parameters(),lr=0.1)\n",
    "alices_opt = optim.SGD(params=alices_model.parameters(),lr=0.1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 4: ट्रेन बॉब और ऐलिस के मॉडल (समानांतर में)\n",
    "\n",
    "जैसा कि सिक्योर एवरेजिंग के माध्यम से फेडरेटेड लर्निंग के साथ पारंपरिक है, प्रत्येक डेटा अधिकारी पहले मॉडल को एक साथ औसतन होने से पहले स्थानीय रूप से कई पुनरावृत्तियों के लिए अपने मॉडल को प्रशिक्षित करता है।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(10):\n",
    "\n",
    "    # Train Bob's Model\n",
    "    bobs_opt.zero_grad()\n",
    "    bobs_pred = bobs_model(bobs_data)\n",
    "    bobs_loss = ((bobs_pred - bobs_target)**2).sum()\n",
    "    bobs_loss.backward()\n",
    "\n",
    "    bobs_opt.step()\n",
    "    bobs_loss = bobs_loss.get().data\n",
    "\n",
    "    # Train Alice's Model\n",
    "    alices_opt.zero_grad()\n",
    "    alices_pred = alices_model(alices_data)\n",
    "    alices_loss = ((alices_pred - alices_target)**2).sum()\n",
    "    alices_loss.backward()\n",
    "\n",
    "    alices_opt.step()\n",
    "    alices_loss = alices_loss.get().data\n",
    "    \n",
    "    print(\"Bob:\" + str(bobs_loss) + \" Alice:\" + str(alices_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 5: एक सुरक्षित कार्यकर्ता को दोनों अद्यतन मॉडल भेजें\n",
    "\n",
    "अब जब प्रत्येक डेटा अधिकारी के पास आंशिक रूप से प्रशिक्षित मॉडल है, तो उन्हें सुरक्षित तरीके से एक साथ औसत करने का समय है। हम ऐलिस और बॉब को उनके मॉडल को सुरक्षित (विश्वसनीय) सर्वर पर भेजने के निर्देश देकर इसे प्राप्त करते हैं।\n",
    "\n",
    "ध्यान दें कि हमारे एपीआई के इस उपयोग का अर्थ है कि प्रत्येक मॉडल को सुरक्षित रूप से सुरक्षित_वर्कर को भेजा जाता है। हम इसे कभी नहीं देखते हैं।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "alices_model.move(secure_worker)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "bobs_model.move(secure_worker)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# चरण 6: औसत मॉडल"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "अंत में, इस प्रशिक्षण युग के लिए अंतिम चरण बॉब और एलिस के प्रशिक्षित मॉडलों को एक साथ औसत करना है और फिर हमारे वैश्विक \"मॉडल\" के लिए मूल्यों को निर्धारित करने के लिए इसका उपयोग करना है।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with torch.no_grad():\n",
    "    model.weight.set_(((alices_model.weight.data + bobs_model.weight.data) / 2).get())\n",
    "    model.bias.set_(((alices_model.bias.data + bobs_model.bias.data) / 2).get())\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# दोहराएं\n",
    "\n",
    "और अब हमें बस इस कई बार पुनरावृति करने की आवश्यकता है!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "iterations = 10\n",
    "worker_iters = 5\n",
    "\n",
    "for a_iter in range(iterations):\n",
    "    \n",
    "    bobs_model = model.copy().send(bob)\n",
    "    alices_model = model.copy().send(alice)\n",
    "\n",
    "    bobs_opt = optim.SGD(params=bobs_model.parameters(),lr=0.1)\n",
    "    alices_opt = optim.SGD(params=alices_model.parameters(),lr=0.1)\n",
    "\n",
    "    for wi in range(worker_iters):\n",
    "\n",
    "        # Train Bob's Model\n",
    "        bobs_opt.zero_grad()\n",
    "        bobs_pred = bobs_model(bobs_data)\n",
    "        bobs_loss = ((bobs_pred - bobs_target)**2).sum()\n",
    "        bobs_loss.backward()\n",
    "\n",
    "        bobs_opt.step()\n",
    "        bobs_loss = bobs_loss.get().data\n",
    "\n",
    "        # Train Alice's Model\n",
    "        alices_opt.zero_grad()\n",
    "        alices_pred = alices_model(alices_data)\n",
    "        alices_loss = ((alices_pred - alices_target)**2).sum()\n",
    "        alices_loss.backward()\n",
    "\n",
    "        alices_opt.step()\n",
    "        alices_loss = alices_loss.get().data\n",
    "    \n",
    "    alices_model.move(secure_worker)\n",
    "    bobs_model.move(secure_worker)\n",
    "    with torch.no_grad():\n",
    "        model.weight.set_(((alices_model.weight.data + bobs_model.weight.data) / 2).get())\n",
    "        model.bias.set_(((alices_model.bias.data + bobs_model.bias.data) / 2).get())\n",
    "    \n",
    "    print(\"Bob:\" + str(bobs_loss) + \" Alice:\" + str(alices_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "अंत में, हम यह सुनिश्चित करना चाहते हैं कि हमारा परिणामी मॉडल सही तरीके से सीखे, इसलिए हम इसका मूल्यांकन एक परीक्षण डेटासेट पर करेंगे। इस छोटी सी समस्या में, हम मूल डेटा का उपयोग करेंगे, लेकिन व्यवहार में हम यह समझने के लिए नए डेटा का उपयोग करना चाहेंगे कि मॉडल अनदेखी उदाहरणों के लिए कितना सामान्य है।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "preds = model(data)\n",
    "loss = ((preds - target) ** 2).sum()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(preds)\n",
    "print(target)\n",
    "print(loss.data)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "इस छोटे उदाहरण में, औसत मॉडल स्थानीय स्तर पर प्रशिक्षित एक सादे मॉडल के सापेक्ष व्यवहार कर रहा है, हालांकि हम प्रत्येक कार्यकर्ता के प्रशिक्षण डेटा को उजागर किए बिना इसे प्रशिक्षित करने में सक्षम थे। हम मॉडल अधिकारी को डेटा रिसाव को रोकने के लिए एक विश्वसनीय एग्रीगेटर पर प्रत्येक कार्यकर्ता से अपडेट किए गए मॉडल को एकत्र करने में सक्षम थे।\n",
    "\n",
    "भविष्य के ट्यूटोरियल में, हम अपने विश्वसनीय एकत्रीकरण को सीधे ग्रेडिएंट के साथ करने का लक्ष्य रखेंगे, ताकि हम मॉडल को बेहतर ग्रेडिएंट अनुमानों के साथ अपडेट कर सकें और एक मजबूत मॉडल पर पहुंच सकें।"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# बधाई हो!!! - समुदाय में शामिल होने का समय!\n",
    "\n",
    "इस नोटबुक ट्यूटोरियल को पूरा करने पर बधाई! यदि आपने इसका आनंद लिया है और एआई और एआई सप्लाई चेन (डेटा) के विकेन्द्रीकृत स्वामित्व के संरक्षण की ओर आंदोलन में शामिल होना चाहते हैं, तो आप निम्न तरीकों से ऐसा कर सकते हैं!\n",
    "\n",
    "### GitHub पर स्टार PySyft\n",
    "\n",
    "हमारे समुदाय की मदद करने का सबसे आसान तरीका सिर्फ रिपॉजिटरी को अभिनीत करना है! यह हमारे द्वारा बनाए जा रहे कूल टूल्स के बारे में जागरूकता बढ़ाने में मदद करता है।\n",
    "\n",
    "- [स्टार PySyft](https://github.com/OpenMined/PySyft)\n",
    "\n",
    "### हमारे Slack में शामिल हों!\n",
    "\n",
    "नवीनतम प्रगति पर अद्यतित रहने का सबसे अच्छा तरीका हमारे समुदाय में शामिल होना है! [http://slack.openmined.org](http://slack.openmined.org) पर फॉर्म भरकर आप ऐसा कर सकते हैं\n",
    "\n",
    "### एक कोड परियोजना में शामिल हों!\n",
    "\n",
    "हमारे समुदाय में योगदान करने का सबसे अच्छा तरीका एक कोड योगदानकर्ता बनना है! किसी भी समय आप PySyft GitHub जारी करने वाले पृष्ठ पर जा सकते हैं और \"Projects\" के लिए फ़िल्टर कर सकते हैं। यह आपको सभी शीर्ष स्तर के टिकट दिखाएगा कि आप किन परियोजनाओं में शामिल हो सकते हैं! यदि आप किसी परियोजना में शामिल नहीं होना चाहते हैं, लेकिन आप थोड़ी सी कोडिंग करना चाहते हैं, तो आप \"good first issue\" चिह्नित गीथहब मुद्दों की खोज करके अधिक \"one off\" मिनी-प्रोजेक्ट्स की तलाश कर सकते हैं।\n",
    "\n",
    "- [PySyft Projects](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3AProject)\n",
    "- [Good First Issue Tickets](https://github.com/OpenMined/PySyft/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)\n",
    "\n",
    "### दान करना\n",
    "\n",
    "यदि आपके पास हमारे कोडबेस में योगदान करने का समय नहीं है, लेकिन फिर भी समर्थन उधार देना चाहते हैं, तो आप हमारे ओपन कलेक्टिव में भी एक बैकर बन सकते हैं। सभी दान हमारी वेब होस्टिंग और अन्य सामुदायिक खर्च जैसे कि हैकाथॉन और मीटअप की ओर जाते हैं!\n",
    "\n",
    "[OpenMined का ओपन कलेक्टिव पेज](https://opencollective.com/openmined)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "nbTranslate": {
   "displayLangs": [
    "hi"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "hi",
   "useGoogleTranslate": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
